/* vim: set sw=8 ts=8 sts=8 expandtab: */
#ifndef CMAID_CACHE_FUNCDEF_H
#define CMAID_CACHE_FUNCDEF_H

/**
 * @def CMAID_CACHE_FUNC(c)
 * @ingroup Cmaid_Cache_Interface
 * Macro to access the cache interface.
 */
#define CMAID_CACHE_FUNC(c) ((const Cmaid_Cache_Interface *)(((c)->interface)))

/**
 * @param s The cache to get an instance
 * @param data The object to cache
 * @return Returns the reference of the cached object
 * @brief Caches an object for reuse
 *
 * The cache will return the address of the data that is already cached and
 * increase the internal object reference count. If there is not a matching
 * object inside of the cache, a new one will be created and returned.
 */
CMAID_INLINE void *
cmaid_cache_instance(Cmaid_Cache *s, const void *data)
{
        return CMAID_CACHE_FUNC(s)->instance(s, data);
}

/**
 * @param s The cache to release an instance
 * @param data The object to be released
 * @return Returns no value
 * @brief Decrease the reference count of the given object
 *
 * The cache will decrease the reference of the given object. If the object
 * is not used else where, the object will be destroyed. Do not use the
 * object reference after this, because you cannot be sure if it is still a
 * legal address.
 */
CMAID_INLINE void
cmaid_cache_release(Cmaid_Cache *s, const void *data)
{
        CMAID_CACHE_FUNC(s)->release(s, data);
}

#endif
